# -*- coding: UTF-8 -*
from Tkinter import *
import Pyro.core # on importe seulement le module central de Pyro

class Vue_Partie():
    def __init__(self, parent, root, nbLignes, nbColonnes, monde, nom):
        self.parent = parent
        self.hauteur = 600   #Hauter en pixels du canvas
        self.largeur = 600   #Largeur en pixels du canvas
        self.intervalleX = int(self.largeur / nbColonnes)    #Intervalle sur l'axe des X entre 2 cases
        self.intervalleY = int(self.hauteur / nbLignes)      #Intervalle sur l'axe des Y entre 2 cases
        self.ecartX = self.intervalleX/2
        self.ecartY = self.intervalleY/2
        self.direction = "devant"      #direction de frogger
        self.nom = nom  #Nom du joueur
        
        self.couleur = "grey"
        
        self.root = root
        self.root.config(bg = self.couleur)
        
        self.accesImages()
        
        self.dessinePartie(monde, nbLignes, nbColonnes)
        self.dessineChat()
    
    
    def accesImages(self):
        #images des grenouilles
        self.imagesGren = {}
        for i in range (4): #i+1 correspondra au numéro de joueur
            fichier  = "images/PartieClassique/frog-" + str(i+1) + ".gif"
            self.imagesGren["grenAvant" + str(i+1)] = PhotoImage(file=fichier)
            
            fichier  = "images/PartieClassique/frogDroite-" + str(i+1) + ".gif"
            self.imagesGren["grenDroite" + str(i+1)] = PhotoImage(file=fichier)
            
            fichier  = "images/PartieClassique/frogGauche-" + str(i+1) + ".gif"
            self.imagesGren["grenGauche" + str(i+1)] = PhotoImage(file=fichier)
            
            fichier  = "images/PartieClassique/frogDerriere-" + str(i+1) + ".gif"
            self.imagesGren["grenDerriere" + str(i+1)] = PhotoImage(file=fichier)
            
            fichier  = "images/PartieClassique/frogAnse-" + str(i+1) + ".gif"
            self.imagesGren["grenAnse" + str(i+1)] = PhotoImage(file=fichier)

        #images des voitures et billots
        self.imgCar1 = PhotoImage(file="images/PartieClassique/car-1.gif")
        self.imgCar2 = PhotoImage(file="images/PartieClassique/car-2.gif")
        self.imgLog1 = PhotoImage(file="images/PartieClassique/billot1.gif")
        self.imgLog2 = PhotoImage(file="images/PartieClassique/billot2.gif")
        self.imgLog3 = PhotoImage(file="images/PartieClassique/billot3.gif")
        
        self.imgTortue1 = PhotoImage(file="images/PartieClassique/tortue-1A.gif")
        self.imgTortue2 = PhotoImage(file="images/PartieClassique/tortue-1B.gif")
        self.imgTortue3 = PhotoImage(file="images/PartieClassique/tortue-1C.gif")
        self.imgTortue4 = PhotoImage(file="images/PartieClassique/tortue-1D.gif")
    
    def dessinePartie(self, monde, nbLignes, nbColonnes):
        
        self.canvas = Canvas(self.root, width = self.hauteur, height = self.largeur, bg = "black")
        self.canvas.pack()
        
        self.dessineMonde(monde, nbLignes, nbColonnes)     
    
        self.canvas.create_rectangle(0,0,self.largeur,self.hauteur, fill = "red", outline="red", tags = "cachePartie")
    
        self.bindings()

        
    def bindings(self):
        self.canvas.unbind("a")
        self.canvas.unbind("b")
        self.canvas.unbind("c")
        self.canvas.unbind("d")
        self.canvas.unbind("e")
        self.canvas.unbind("f")
        self.canvas.unbind("g")
        self.canvas.unbind("h")
        self.canvas.unbind("i")
        self.canvas.unbind("j")
        self.canvas.unbind("k")
        self.canvas.unbind("l")
        self.canvas.unbind("m")
        self.canvas.unbind("n")
        self.canvas.unbind("o")
        self.canvas.unbind("p")
        self.canvas.unbind("q")
        self.canvas.unbind("r")
        self.canvas.unbind("s")
        self.canvas.unbind("t")
        self.canvas.unbind("u")
        self.canvas.unbind("v")
        self.canvas.unbind("w")
        self.canvas.unbind("x")
        self.canvas.unbind("y")
        self.canvas.unbind("z")
        self.canvas.unbind("1")
        self.canvas.unbind("2")
        self.canvas.unbind("3")
        
        self.canvas.bind("d", self.deplacerGrenouille) #appuyer sur d pour droite
        self.canvas.bind("a", self.deplacerGrenouille) #appuyer sur a pour gauche
        self.canvas.bind("w", self.deplacerGrenouille)  #appuyer sur w pour avancer
        self.canvas.bind("s", self.deplacerGrenouille) #appuyer sur s pour reculer
        self.canvas.bind("D", self.deplacerGrenouille) #appuyer sur d pour droite
        self.canvas.bind("A", self.deplacerGrenouille) #appuyer sur a pour gauche
        self.canvas.bind("W", self.deplacerGrenouille)  #appuyer sur w pour avancer
        self.canvas.bind("S", self.deplacerGrenouille) #appuyer sur s pour reculer
        self.canvas.bind("<Button-1>", self.focusJeu) #Pour redonner le focus au jeu après l'utilisation du chat
        #self.canvas.bind(0x18, self.avancer) #appuyer sur up pour avancer
        #self.canvas.bind(0x19, self.reculer) #appuyer sur down pour reculer
        #self.canvas.bind(chr(1A), self.gauche) #appuyer sur left pour gauche
        #self.canvas.bind(chr(1B), self.droite) #appuyer sur right pour droite 
               

        self.canvas.bind("0", self.cheatFinJeu) #cheat pour passer au choix de mini-jeu
    
    def cheatFinJeu(self, event):
        self.parent.cheatFinJeu()

    ###############################
    ###SECTION CHOIX DU MINI JEU###
    ###############################

    #Menu pour choisir le mini-jeu
    def menuChoixJeu(self, nbLignes, nbColonnes):
        self.intervalleX = int(self.largeur / nbColonnes)
        self.intervalleY = int(self.hauteur / nbLignes)
        
        posX=25
        posYText = [2,6,10,14]

        self.canvas.delete("all")

        self.canvas.create_rectangle(0,0,self.largeur,self.hauteur, fill = "black", outline="black", tags = "menuChoixPartie")

        self.canvas.create_text((posX*self.intervalleX),(posYText[0]*self.intervalleY),text = "Frogger Plateforme" ,font=("Ravie","15","bold italic"),fill="darkgreen")
        self.canvas.create_text((posX*self.intervalleX),(posYText[1]*self.intervalleY),text = "Frogger Labyrinthe" ,font=("Ravie","15","bold italic"),fill="darkgreen")
        self.canvas.create_text((posX*self.intervalleX),(posYText[2]*self.intervalleY),text = "Frogger Dance" ,font=("Ravie","15","bold italic"),fill="darkgreen")
        self.canvas.create_text((posX*self.intervalleX),(posYText[3]*self.intervalleY),text = "Frogger Shoot" ,font=("Ravie","15","bold italic"),fill="darkgreen")
                
        self.bindingsChoixPartie()
        
    def bindingsChoixPartie(self):
        self.canvas.bind("f", self.deplacerMenuChoixJeu) #appuyer sur f pour sélectionner
        self.canvas.bind("F", self.deplacerMenuChoixJeu) 
        self.canvas.bind("s", self.deplacerMenuChoixJeu) #appuyer sur s pour bas
        self.canvas.bind("S", self.deplacerMenuChoixJeu) 
        self.canvas.bind("w", self.deplacerMenuChoixJeu) #appuyer sur w pour haut
        self.canvas.bind("W", self.deplacerMenuChoixJeu)
        
    #Déplacement du curseur pour le menu de choix de mini jeu
    def deplacerMenuChoixJeu(self, event):
        if (event.char == 'W' or event.char == 'w'):
            self.direction = "haut"
        elif (event.char == 'S' or event.char == 's'):
            self.direction = "bas"
        elif (event.char == 'F' or event.char == 'f'):
            self.direction = "choix"     
            
        self.parent.deplacerCurseur(self.direction)
        
        #Dessin du curseur dans le menu mini-jeu
    def dessineCurseur(self, pos, noJoueur):
        posX = 10       #Positionner le curseur
        posYText = [2,6,10,14]
        posY = posYText[pos-1]
        self.canvas.delete("curseur")    #On efface tous les objets du canvas qui ont "curseur" comme tag
        
        self.canvas.create_image((posX*self.intervalleX),(posY*self.intervalleY),image=self.imagesGren["grenAvant" + str(noJoueur)],tags=("curseur"))  
   
    ##################
    ###SECTION CHAT###
    ##################
    
    def dessineChat(self):
        
        fChat = Frame(self.root, bg = self.couleur)
        
        #Frame contanant la liste des joueurs, la liste des pointages et l'avatar
        fGauche = Frame(fChat, bg = self.couleur)
        #Frame contenant la liste des joueurs et la liste des pointages
        fIntG = Frame(fGauche, bg = self.couleur)
        self.utilisateurs = Listbox(fIntG, width = 17, height = 5)
        self.utilisateurs.insert(END, "Joueurs:")
        self.utilisateurs.pack(side = LEFT)
        
        self.pointage = Listbox(fIntG, width = 10, height = 5)
        self.pointage.insert(END, "Points:")
        self.pointage.pack(side = LEFT)
        
        self.niveau = Listbox(fIntG, width = 3, height = 5)
        self.niveau.insert(END, "Niv")
        self.niveau.pack(side = LEFT)
        fIntG.pack(side = TOP)
        
        #Avatars
        self.avatars = {}
        self.avatars["gChat"] = PhotoImage(file="images\\Avatars\\chat_grenouille.gif")
        self.avatars["g1"] = PhotoImage(file="images\\Avatars\\grenouille_fol_oeil.gif")
        self.avatars["g2"] = PhotoImage(file="images\\Avatars\\grenouille1.gif")
        self.avatars["g3"] = PhotoImage(file="images\\Avatars\\grenouille2.gif")
        
        
        self.avatar = Canvas(fGauche, width = 139, height = 94, bg = "black")
        self.avatar.pack(side = TOP, pady = 5)
        self.avatar.create_image(71,49,image=self.avatars["gChat"],tags=("avatar"))
        
        fGauche.pack(side = LEFT, padx = 5, pady = 5)
        
        #Frame de droite contenant les 2 zones de text et le boutton d'envoi
        fDroit = Frame(fChat, bg = self.couleur)
        
        #Zone de texte d'affichage
        fAffichage = Frame(fDroit, bg = self.couleur)
        outputScroll = Scrollbar(fAffichage)
        self.output = Text(fAffichage, width = 35, height = 8, state = DISABLED)
        outputScroll.config(command = self.output.yview)
        self.output.config(yscrollcommand = outputScroll.set)
        self.output.pack(side = LEFT, expand = 1, fill = BOTH)
        outputScroll.pack(side = LEFT, fill = Y)
        fAffichage.pack(side = TOP, padx = 5, pady = 5, expand = 1, fill = BOTH)
        
        #Frame du bas contenant la zone de texte de saisie et le boutton d'envoi
        fBas = Frame(fDroit, bg = self.couleur)
        inputScroll = Scrollbar(fBas)
        self.input = Text(fBas, width = 25, height = 2)
        inputScroll.config(command = self.input.yview)
        self.input.config(yscrollcommand = inputScroll.set)
        self.input.pack(side = LEFT, expand = 1, fill = BOTH)
        inputScroll.pack(side = LEFT, fill = Y)
        fBas.pack(side = TOP, padx = 3, pady = 3, expand = 1, fill = BOTH)
        
        self.input.bind("<Return>", self.envoi) #Lie l'envoi d'un message avec le boutton Enter
        
        fDroit.pack(side = LEFT, padx = 5, pady = 5, expand = 1, fill = BOTH)
        fChat.pack(side = TOP, expand = 1, fill = X)
    
    
    ###########################
    #####MÉTHODES PARTIE#######
    ###########################
    #On parcourt le tableau du monde et pour chaque élément, on vien dessiner un rectangle de la couleur correspondante 
    def dessineMonde(self, monde, nbLignes, nbColonnes):
        
        self.canvas.delete("all")
        self.intervalleY = int(self.hauteur / nbLignes)      #Intervalle sur l'axe des Y entre 2 cases
        
        
        posX = 0
        posY = 0
        
        for i in range(nbLignes):
            for j in range(nbColonnes):
                
                if (j == 0 and i!= 0):  #lorsqu'on termine une ligne, on augment d'une ligne et on recommence à la colonne 1
                    posX = 0
                    posY += self.intervalleY
                if (monde[i][j] == "anse"):   #les anses sont noires
                    self.canvas.create_rectangle(posX, posY,posX+self.intervalleX, posY+self.intervalleY, fill = "black", outline="black")
                elif (monde[i][j] == "ansePrise"): #anses noires avec image grenouille
                    self.canvas.create_rectangle(posX, posY,posX+self.intervalleX, posY+self.intervalleY, fill = "#202020", outline="#202020")
                elif (monde[i][j] == "marais"):   #Les vides sont bleus
                    self.canvas.create_rectangle(posX, posY,posX+self.intervalleX, posY+self.intervalleY, fill = "green", outline="green")
                elif (monde[i][j] == "riviere"):   #Le sol est vert
                    self.canvas.create_rectangle(posX, posY,posX+self.intervalleX, posY+self.intervalleY, fill = "#101099", outline="#101099")
                elif (monde[i][j] == "berge"):   #Le sol est vert
                    self.canvas.create_rectangle(posX, posY,posX+self.intervalleX, posY+self.intervalleY, fill = "#864", outline="#864")
                elif (monde[i][j] == "route"):   #Le sol est vert
                    self.canvas.create_rectangle(posX, posY,posX+self.intervalleX, posY+self.intervalleY, fill = "grey", outline="grey")
                posX += self.intervalleX
        
    def dessineGrenAnse(self, monde, nbLignes, nbColonnes, noJoueur, niveau):       
        #on trouve les anses prises et on pose une images de grenouille au milieu de l'anse
        posY = 1 #les anses sont sur la ligne 1
        
        #on doit ajuster la position de l'image en fonction du niveau car le nombre de lignes change
        if(niveau==1):
            ecartY = self.ecartY
        elif(niveau==2):
            ecartY = self.ecartY*4/5
        else:
            ecartY = self.ecartY/2
        
        #on trouve les anses prises
        for posX in range (nbColonnes):
            if (monde[posY][posX] == "ansePrise" and monde[posY][posX-1]== "ansePrise" and monde[posY][posX+1]== "ansePrise"):
                self.canvas.create_image((posX*self.intervalleX)+self.ecartX, (posY*self.intervalleY)+ecartY, image=self.imagesGren["grenAnse" + str(noJoueur)],tags=("grenAnse"))
    
    #Avec la position et les intervalles entre les cases (en X et en Y), on vient dessiner la grenouille sur le canvas
    def dessineGrenouille(self, pos, noJoueur, niveau):
        self.canvas.delete("grenouille")    #On efface tous les objets du canvas qui ont "grenouille" comme tag
        
        decalage = 0 #Pour recentré la grenouille lorsque les lignes diminuent de taille
        
        if (niveau == 2):
            decalage = 4
        elif (niveau == 3):
            decalage = 9
        
        if(self.direction=="droite"):        
            self.canvas.create_image((pos[0]*self.intervalleX)+self.ecartX,(pos[1]*self.intervalleY)+self.ecartY-decalage, image=self.imagesGren["grenDroite" + str(noJoueur)],tags=("grenouille"))
        elif(self.direction=="gauche"):        
            self.canvas.create_image((pos[0]*self.intervalleX)+self.ecartX,(pos[1]*self.intervalleY)+self.ecartY-decalage,image=self.imagesGren["grenGauche" + str(noJoueur)],tags=("grenouille"))
        elif(self.direction=="derriere"):        
            self.canvas.create_image((pos[0]*self.intervalleX)+self.ecartX,(pos[1]*self.intervalleY)+self.ecartY-decalage,image=self.imagesGren["grenDerriere" + str(noJoueur)],tags=("grenouille")) 
        else:      
            self.canvas.create_image((pos[0]*self.intervalleX)+self.ecartX,(pos[1]*self.intervalleY)+self.ecartY-decalage,image=self.imagesGren["grenAvant" + str(noJoueur)],tags=("grenouille"))          
        self.canvas.update()    #Pour redissiner le canvas après chaque modification (utile lorsqu'on utilise un timer (ex: chuteLibre())
                                #L'image est rafraichie après chaque boucle plutôt qu'uniquement à la fin de la chute
                               
                                        
    def deplacerGrenouille(self, event):
        
        if (event.char == 'W' or event.char == 'w'):
            self.direction = "devant"
        elif (event.char == 'A' or event.char == 'a'):
            self.direction = "gauche"
        elif (event.char == 'D' or event.char == 'd'):
            self.direction = "droite"
        elif (event.char == 'S' or event.char == 's'):
            self.direction = "derriere"
            
        self.pos = self.parent.deplacerGrenouille(self.direction)
        
    def focusJeu(self, e):  #Recevoir le focus au clic de souris
        #if (self.parent.enMiniJeu == False):
        self.canvas.focus_set()
            
    def retireFocus(self):
        self.avatar.focus_set() #Elève le focus du jeu principal et le donne à l'avatar du joueur pour 
    
    ########################
    #####MÉTHODES CHAT######
    ########################
    def envoi(self, e):
        #if (self.parent.enMiniJeu == False):
        self.canvas.focus_set() #Redonne le focus au jeu après avoir envoyé un message
        
        if  self.input.get('1.0',END) != "\n":    #Une zone de texte contient toujours un "\n" il n'est donc jamais vide!!!
            
            mess = self.input.get('1.0',END)
            self.input.delete('1.0', END)
            self.output.yview(END)      #Descend la scrollbar pour voir les derniers messages entr�s
            self.parent.envoiMess(self.nom, mess)
    
    def recevoir(self, nom, mess):
        self.output.config(state = NORMAL)
        self.output.insert(END, "\n-- " + nom + " --\n" + mess)
        self.output.yview(END) #Replace la barre de défilement au bas du chat
        self.output.config(state = DISABLED)
        
    def majUsagers(self, listeUtilisateurs):
        self.utilisateurs.delete(1, END)
        self.pointage.delete(1, END)
        self.niveau.delete(1, END)
                
        for i in listeUtilisateurs:
            self.utilisateurs.insert(END, str(i.no) + "- " + i.nom)
            self.pointage.insert(END, i.score)
            self.niveau.insert(END, i.niveau)
            
    def enAttente(self):    #On dessine un rectangle vert pour indiquer le départ de la partie dans quelques insntants
        self.canvas.delete("cachePartie")
        self.canvas.create_rectangle(0,0,self.largeur,self.hauteur, fill = "green", outline="green", tags = "cachePartie")
            
    def commencerPartie(self): ####
        #On donne le focus au canvas pour que ce soit lui qui reçoive les événements provenant du clavier
        self.canvas.focus_set()
        
        self.canvas.delete("cachePartie")
        
    def afficheBillot(self,billot):
        self.canvas.delete("billot")
        for i in billot:
            #si l'orientation est à droite
            if (i.orientation==1):
                posX = i.posX + i.longueur/2
            #si l'orientation est à gauche
            else:
                posX = i.posX - i.longueur/2 + 1
            posY = i.ligne
            
            #s'il s'git d'un bilot moyen
            if (i.longueur == 7):
                self.canvas.create_image(posX*self.intervalleX, posY*self.intervalleY+self.intervalleY/2, image=self.imgLog1, tags = ("billot"))
            #s'il s'git d'un bilot court
            elif (i.longueur == 5):
                self.canvas.create_image(posX*self.intervalleX, posY*self.intervalleY+self.intervalleY/2, image=self.imgLog3, tags = ("billot"))
            #s'il s'agit d'un billot long
            else:
                self.canvas.create_image(posX*self.intervalleX, posY*self.intervalleY+self.intervalleY/2, image=self.imgLog2, tags = ("billot"))
    
    def afficheVoiture(self,voitures):
        self.canvas.delete("voiture")
        for i in voitures:
            posX = i.posX
            posY = i.ligne
            if(posY%2==1):
                self.canvas.create_image(posX*self.intervalleX+self.intervalleX/2, posY*self.intervalleY+self.intervalleY/2,image=self.imgCar1, tags = ("voiture"))
                #self.canvas.create_rectangle(posX*self.intervalleX+5, posY*self.intervalleY+5, (posX+1)*self.intervalleX-5, (posY+1)*self.intervalleY-5,fill = "blue", tags = "voiture", outline = "blue")
            else:
                self.canvas.create_image(posX*self.intervalleX+self.intervalleX/2, posY*self.intervalleY+self.intervalleY/2,image=self.imgCar2, tags = ("voiture"))
      
    def afficheTortue(self, tortues):
        self.canvas.delete("tortue")
        
        for i in tortues:
            posX = i.posX
            posY = i.ligne
           
            if (i.etat < 5):
                self.canvas.create_image( (posX)*self.intervalleX, posY*self.intervalleY+self.intervalleY/2,image=self.imgTortue1, tags = ("tortue"))
            elif (i.etat < 10):
                self.canvas.create_image( (posX)*self.intervalleX, posY*self.intervalleY+self.intervalleY/2,image=self.imgTortue2, tags = ("tortue"))
            elif (i.etat < 13):
                self.canvas.create_image( (posX)*self.intervalleX, posY*self.intervalleY+self.intervalleY/2,image=self.imgTortue3, tags = ("tortue"))
            elif (i.etat < 16):
                self.canvas.create_image( (posX)*self.intervalleX, posY*self.intervalleY+self.intervalleY/2,image=self.imgTortue4, tags = ("tortue"))
            elif (i.etat < 19):
                pass
            elif (i.etat < 22):
                self.canvas.create_image( (posX)*self.intervalleX, posY*self.intervalleY+self.intervalleY/2,image=self.imgTortue4, tags = ("tortue"))
            elif (i.etat < 25):
                self.canvas.create_image( (posX)*self.intervalleX, posY*self.intervalleY+self.intervalleY/2,image=self.imgTortue3, tags = ("tortue"))
            elif (i.etat < 30):
                self.canvas.create_image( (posX)*self.intervalleX, posY*self.intervalleY+self.intervalleY/2,image=self.imgTortue2, tags = ("tortue"))
            else:
                self.canvas.create_image( (posX)*self.intervalleX, posY*self.intervalleY+self.intervalleY/2,image=self.imgTortue1, tags = ("tortue"))
                 
            
    ########################
    #######FIN DE JEU#######
    ########################
    
    def afficherFinDeJeu (self, utilisateurs):
 
        posX = 25
        posYText = [1,4,7,10,14]
        self.canvas.focus_set()
        self.canvas.delete("all")
        self.canvas.bind("<Return>", self.highScores)
        self.canvas.create_rectangle(0,0,self.largeur,self.hauteur, fill = "black", outline="black", tags = "finPartie")
        
        self.canvas.create_text((posX*self.intervalleX)+self.ecartX,(posYText[0]*self.intervalleY)+self.ecartY,text = "Pointage final" ,font=("Ravie","15","bold italic"),fill="darkgreen")
        for enum,i in enumerate(utilisateurs):
                texte = i.nom + "- " + str(i.score)
                self.canvas.create_text((posX*self.intervalleX)+self.ecartX,(posYText[enum+1]*self.intervalleY)+self.ecartY,text = texte ,font=("Ravie","15","bold italic"),fill="darkgreen")

    def afficherHighScores(self, tabHighScores):
        posX = 25
        posYText = [1,4,6,8,10,12]
        self.canvas.focus_set()
        self.canvas.delete("all")
        self.canvas.bind("<Return>", self.quitterJeu)
        self.canvas.create_rectangle(0,0,self.largeur,self.hauteur, fill = "black", outline="black", tags = "finPartie")
        
        self.canvas.create_text((posX*self.intervalleX)+self.ecartX,(posYText[0]*self.intervalleY)+self.ecartY,text = "Meilleurs joueurs" ,font=("Ravie","15","bold italic"),fill="darkgreen")
        for i in range(5):
            temp = tabHighScores[i]
            texte = str(i+1) + " - " + str(temp[1]) + " - " + str(temp[2])
            self.canvas.create_text((posX*self.intervalleX)+self.ecartX,(posYText[i+1]*self.intervalleY)+self.ecartY,text = texte ,font=("Ravie","15","bold italic"),fill="darkgreen")        

    def highScores(self, event):
        self.parent.afficherHighScoresFinPartie()
        
    def quitterJeu(self, event):
        self.parent.quitterPartie()



